
#ifndef	__MT_CAMERA_H__
#define	__MT_CAMERA_H__


#define	MODULE_VERSION			0x0101	// Ver 01.01

#define	CAMERA_MAX_NUM			2
#define	TOUCH_DATA_MAX_NUM		2
#define	TOUCH_DATA_MAX_VALUE	0x7FFF
#define	RADIAN_DATA_MAX_NUM		TOUCH_DATA_MAX_NUM	// Camera -> Touch -> PC
#define	LINEEQ_DATA_MAX_NUM		RADIAN_DATA_MAX_NUM	// Camera -> Touch
#define	POINT_DATA_MAX_NUM		(LINEEQ_DATA_MAX_NUM * LINEEQ_DATA_MAX_NUM)

#define	CAMERA_ID0				0
#define	CAMERA_ID1				1
#define	CAMERA_ID2				2
#define	CAMERA_ID3				3


#ifndef	M_PI
#define M_PI					(float)3.141592653589793238//4626433832795028841971693993751058209749445923078164062862089986280348253421170679
#endif
#define	DEGREE_TO_RADIAN(d)		(float)(((d) * M_PI) / 180.)
#define	RADIAN_TO_DEGREE(r)		(float)(((r) * 180.) / M_PI)
#define	PERCENT_TO_POINT(p)		(float)((p) * 0.01)

#define	DEV_TOUCH				0
#define	DEV_CAMERA1				1
#define	DEV_CAMERA2				2
#define	DEV_CAMERA3				3
#define	DEV_CAMERA4				4
//...


//               0    1    2    3     4
// USB <-> USB : RID  CMD  DEV  DLEN [DATA ...]
#define	USB_PKT_MAX_LEN			64
#define	USB_PKT_HEAD_LEN		4
#define	USB_PKT_DATA_MAX_LEN	(USB_PKT_MAX_LEN - USB_PKT_HEAD_LEN)
#define	USB_PKT_REPORT_ID		0x21	// <usbd_conf.h> HID_REPORT_ID
#define	USB_PKT_POS_RID			0
#define	USB_PKT_POS_CMD			1
#define	USB_PKT_POS_DEV			2
#define	USB_PKT_POS_DLEN		3
#define	USB_PKT_POS_DATA		4

#define	USB_PKT_DLEN_Make(c,l)	(unsigned char)((((c) & 0x1) << 7) | (((l) & 0x7F) << 0))
#define	USB_PKT_DLEN_IsCont(c)	((c) & (1 << 7))
#define	USB_PKT_DLEN_GetLen(l)	(unsigned char)((l) & 0x7F)

//               0    1    2    3     4      5
// UART<->UART : SOH0 SOH1 SOH2 SOH3  CMD  DEV  DLEN0 DLEN1 [DATA ...]
#define	UART_PKT_MAX_LEN		3072	// 4096
#define	UART_PKT_HEAD_LEN		8		// 4 + 4
#define	UART_PKT_MAX_DATA_LEN	(UART_PKT_MAX_LEN - UART_PKT_HEAD_LEN)
#define	UART_PKT_SOHS			"PKTS"	// start of heading
#define	UART_PKT_POS_SOH0		0
#define	UART_PKT_POS_SOH1		1
#define	UART_PKT_POS_SOH2		2
#define	UART_PKT_POS_SOH3		3
#define	UART_PKT_POS_CMD		4
#define	UART_PKT_POS_DEV		5
#define	UART_PKT_POS_DLEN0		6
#define	UART_PKT_POS_DLEN1		7
#define	UART_PKT_POS_DATA		8


#define	RESET_IAP				0x00	// Util_ResetWWDG();
#define	RESET_APP				0x01	// NVIC_SystemReset();


#define	FWTYPE_IAP				0x00	// 
#define	FWTYPE_APP				0x01	// 
#define	FWTYPE_SAVE_APP			0x02	// 
#define	FWTYPE_SAVE_IAP			0x03	// 


#define	OSTYPE_UNKNOWN			0x00
#define	OSTYPE_WINDOWS			0x01
#define	OSTYPE_LINUX			0x02
#define	OSTYPE_ANDROID			0x03


#define	STATE_UNKNOWN			0
#define	STATE_IAP_INIT			11
#define	STATE_IAP_UPGRADE		12
#define	STATE_INIT				21
#define	STATE_TOUCH				22
#define	STATE_SIDEVIEW			23	// detection_line, light
#define	STATE_DETECTION			24	// range, threshold
#define	STATE_CALIBRATION		25	// time, area, sensitivity


#define	DATA_EEPROM_START_VAL	0xF001

#define	DATA_FILTER_NUM_MIN		2
#define	DATA_FILTER_NUM_DEF		6
#define	DATA_FILTER_NUM_MAX		12

#define	DATA_INPUT_MODE_MOUSE	0
#define	DATA_INPUT_MODE_SINGLE	1
#define	DATA_INPUT_MODE_MULTI	2

#define	DATA_PWM_NUM			4
#define	DATA_PWM_MIN			0
#define	DATA_PWM_DEF			100
#define	DATA_PWM_MAX			100

#define	DATA_TIME_TAP_MIN		1	//[*100 msec]	 100 msec
#define	DATA_TIME_TAP_DEF		3	//[*100 msec]	 300 msec
#define	DATA_TIME_TAP_MAX		10	//[*100 msec]	1000 msec

#define	DATA_TIME_LTAP_MIN		1	//[*100 msec]	 100 msec
#define	DATA_TIME_LTAP_DEF		20	//[*100 msec]	2000 msec
#define	DATA_TIME_LTAP_MAX		80	//[*100 msec]	8000 msec

#define	DATA_AREA_TAP_MIN		1	//[*0.1 %]	0.1 %
#define	DATA_AREA_TAP_DEF		8	//[*0.1 %]	0.8 %
#define	DATA_AREA_TAP_MAX		15	//[*0.1 %]	1.5 %

#define	DATA_AREA_DTAP_MIN		10	//[*0.1 %]	1.0 %
#define	DATA_AREA_DTAP_DEF		15	//[*0.1 %]	1.5 %
#define	DATA_AREA_DTAP_MAX		30	//[*0.1 %]	3.0 %

#define	DATA_AREA_PALM_MIN		30	//[*0.1 %]	3.0 %
#define	DATA_AREA_PALM_DEF		35	//[*0.1 %]	3.5 %
#define	DATA_AREA_PALM_MAX		60	//[*0.1 %]	6.0 %

#define	DATA_BEEP_ALERT_DEF		1
#define	DATA_BEEP_CLICK_DEF		0

#define	DATA_NOSEND_DEF			0

#define	DATA_ACCEL_MIN			50
#define	DATA_ACCEL_DEF			300


#define	DATA_YCENTER_MIN		-300
#define	DATA_YCENTER_DEF		0
#define	DATA_YCENTER_MAX		300

#define	DATA_XSTART_MIN			0	//25
#define	DATA_XSTART_DEF			10
#define	DATA_XSTART_MAX			400

#define	DATA_XEND_MIN			1200
#define	DATA_XEND_DEF			1590
#define	DATA_XEND_MAX			1599	//1000

#define	DATA_THRESHOLD_MIN		0
#define	DATA_THRESHOLD_DEF		180
#define	DATA_THRESHOLD_MAX		255

#define	DATA_MINWIDTH_MIN		1
#define	DATA_MINWIDTH_DEF		3
#define	DATA_MINWIDTH_MAX		5

#define	DATA_AVERAGELIGHT_MIN	0
#define	DATA_AVERAGELIGHT_DEF	50
#define	DATA_AVERAGELIGHT_MAX	255

#define	DATA_COEFFS_NUM			12	// 8 or 12
#define	DATA_COEFFS_MARGIN_SX	1	//[%]
#define	DATA_COEFFS_MARGIN_LX	25	//[%]
#define	DATA_COEFFS_MARGIN_CX	50	//[%]
#define	DATA_COEFFS_MARGIN_RX	75	//[%]
#define	DATA_COEFFS_MARGIN_EX	99	//[%]
#define	DATA_COEFFS_MARGIN_SY	2	//[%]
#define	DATA_COEFFS_MARGIN_CY	50	//[%]
#define	DATA_COEFFS_MARGIN_EY	95	//[%]


#define	ERR_SUCCESS				0x00
#define	ERR_UNKNOWN_COMMAND		0x01
#define	ERR_UNKNOWN_DEVICE		0x02
#define	ERR_LENGTH_DATA			0x03
//...

#define	TOUCH_ID_0				1
#define	TOUCH_ID_1				2
#define	TOUCH_ID_2				3
#define	TOUCH_ID_3				4
#define	TOUCH_ID_NONE			0xFF

#define	TOUCH_UP				0
#define	TOUCH_DOWN				(1<<0)
#define	TOUCH_INRANGE			(1<<1)

#define	MOUSE_UP				0
#define	MOUSE_LDOWN				(1<<0)
#define	MOUSE_RDOWN				(1<<1)
#define	MOUSE_MDOWN				(1<<2)

#define	TOUCH_FLAG_UP			0x00
#define	TOUCH_FLAG_DOWN			0x01


typedef enum {
	IAP_EEPROM_START=0,
	IAP_SAVE_APP_CHECK,
	IAP_SAVE_APP_TOTAL_SIZE,
	IAP_SAVE_IAP_CHECK,
	IAP_SAVE_IAP_TOTAL_SIZE,
	IAP_RESERVED,
	//...

	CAMERA_IS_SUBADDR=9,

	APP_EEPROM_START=10,

	TOUCH_EEPROM_START=APP_EEPROM_START,
	TOUCH_FILTER_NUM, TOUCH_INPUT_MODE,
	TOUCH_PWM_CH1, TOUCH_PWM_CH2, TOUCH_PWM_CH3, TOUCH_PWM_CH4,
	TOUCH_TIME_TAP, TOUCH_TIME_LTAP,
	TOUCH_AREA_TAP, TOUCH_AREA_DTAP, TOUCH_AREA_PALM,
	TOUCH_BEEP_ALERT, TOUCH_BEEP_CLICK,
	TOUCH_NOSEND,
	TOUCH_ACCEL,
	TOUCH_EEPROM_END,

	CAMERA_EEPROM_START=APP_EEPROM_START,
	CAMERA_YCENTER, CAMERA_XSTART, CAMERA_XEND, CAMERA_THRESHOLD,
	CAMERA_MINWIDTH, CAMERA_AVERAGELIGHT,
	CAMERA_COEFFS_L0, CAMERA_COEFFS_H0, CAMERA_COEFFS_L1, CAMERA_COEFFS_H1,
	CAMERA_COEFFS_L2, CAMERA_COEFFS_H2, CAMERA_COEFFS_L3, CAMERA_COEFFS_H3,
	CAMERA_COEFFS_L4, CAMERA_COEFFS_H4, CAMERA_COEFFS_L5, CAMERA_COEFFS_H5,
	CAMERA_COEFFS_L6, CAMERA_COEFFS_H6, CAMERA_COEFFS_L7, CAMERA_COEFFS_H7,
	CAMERA_COEFFS_L8, CAMERA_COEFFS_H8, CAMERA_COEFFS_L9, CAMERA_COEFFS_H9,
	CAMERA_COEFFS_LA, CAMERA_COEFFS_HA, CAMERA_COEFFS_LB, CAMERA_COEFFS_HB,
	CAMERA_EEPROM_END,
		
	GESTURE_START=50,	// (FLAG, KEY)
	GESTURE_UDRAG, GESTURE_RDRAG, GESTURE_DDRAG, GESTURE_LDRAG,
	GESTURE_TAP, GESTURE_DTAP, GESTURE_LTAP,

	ENDOF_EEPROM=100
} EEPROM_VIRTUAL_ADDRESS;

typedef enum {
	GE_PALM=0xF0, GE_FINGURE, GE_NONE,
	GE_DRAGUP=0, GE_DRAGRIGHT, GE_DRAGDOWN, GE_DRAGLEFT, GE_TAP, GE_TAPDOUBLE, GE_TAPLONG, GE_MAX,
} GESTURE_ENUM;


#pragma pack(1)
typedef struct
{
	unsigned short	wVersion;		// MMmm
	unsigned int	dwBuildTime;	// time_t
} VERSION_DATA, *PVERSION_DATA;
typedef struct
{
	unsigned char	bType;			// fwtype_xxx
	unsigned short	wTotalSize;
} FWINFO_DATA, *PFWINFO_DATA;
typedef struct
{
	unsigned short	wCurSize;
	unsigned short	wTotalSize;
} FWDATA_DATA, *PFWDATA_DATA;
typedef struct
{
	unsigned short	wAddress;
	unsigned short	wData;
} EEPROM_DATA, *PEEPROM_DATA;
typedef struct
{
	unsigned char	bFilterNum;		// 0 ~ 8 : 0(no correction)
	unsigned char	bInputMode;		// 0(Mouse), 1(Sigle-touch), 2(Multi-touch)
	unsigned char	bPWMs[DATA_PWM_NUM];// 0 ~ 100, Ch1~Ch4
	unsigned char	bTimeTap;		//  1 ~ 10 [*100 msec]
	unsigned char	bTimeLTap;		//  1 ~ 80 [*100 msec]
	unsigned char	bAreaTap;		//  1 ~ 15 [*0.1 %]
	unsigned char	bAreaDTap;		// 10 ~ 30 [*0.1 %]
	unsigned char	bAreaPalm;		// 30 ~ 60 [*0.1 %]
	unsigned char	bBeepAlert;		// 0 or 1
	unsigned char	bBeepClick;		// 0 or 1
	unsigned char	bNoSend;		// 0 or 1
	unsigned short	wAccel;			// 50 ~ (300) ~

	unsigned char	bPad[USB_PKT_DATA_MAX_LEN - (1+1+4+2+3+2+1+2) - 2];
} TOUCHCONFIG_DATA, *PTOUCHCONFIG_DATA;
typedef struct
{
	short			nYCenter;		// -300 ~ 300
	unsigned short	wXStart;		// 0 ~ 400
	unsigned short	wXEnd;			// 600 ~ 1023
	unsigned char	bThreshold;		// 0 ~ 255
	unsigned char	bMinWidth;		// 1~5
	unsigned char	bAverageLight;	// 0 ~ 255
	float			fCoeffs[DATA_COEFFS_NUM];

	unsigned char	bPad[USB_PKT_DATA_MAX_LEN - (2+2+2+1+1+1+(4*DATA_COEFFS_NUM)) - 2];
} CAMERACONFIG_DATA, *PCAMERACONFIG_DATA;

typedef struct
{
	unsigned char	bFlag;	// 8(LGui), 4(LAlt), 2(LSft), 1(LCtl)
	unsigned char	bKey;	// 0(release), ...
} GESTURE_ITEM, *PGESTURE_ITEM;
typedef struct
{
	GESTURE_ITEM	g[GE_MAX];
} GESTURE_DATA, *PGESTURE_DATA;

typedef struct
{
	char			x;
	char			y;
} POINT_DELTA, *PPOINT_DELTA;
typedef struct
{
	unsigned short	x;
	unsigned short	y;
} POINT_WORD, *PPOINT_WORD;
typedef struct
{
	float			x;
	float			y;
} POINT_FLOAT, *PPOINT_FLOAT;
typedef struct
{
	float			fCenter;
	float			fStart;
	float			fEnd;
} RADIAN_DATA, *PRADIAN_DATA;
typedef struct
{
	float			fA[3];		// Center, Start, End
	float			fB[3];		// Center, Start, End
} LINEEQ_DATA, *PLINEEQ_DATA;	// Y = AX + B
typedef struct
{
	POINT_FLOAT		fPt;
	unsigned char	bStatus;	// 0(out of range), 1(in range)
	float			fArea;
	float			fRatio;

	unsigned char	bPtIdx;
	float			fErrDist;
} POINT_DATA, *PPOINT_DATA;
typedef struct
{
	unsigned char	bId;
	unsigned char	bFlags;		// TOUCH_FLAG_XXX(UP, DOWN)
	unsigned int	uCount;		// released(==0), pressed(>=1)
	PPOINT_DATA		pNewPoint;

	POINT_FLOAT		fPt;
	POINT_FLOAT		fTotalPt;
	POINT_FLOAT		fSamplesPt[DATA_FILTER_NUM_MAX];

	float			fArea;
	float			fTotalArea;
	float			fSamplesArea[DATA_FILTER_NUM_MAX];

	GESTURE_ENUM	eGesture;
	POINT_FLOAT		ptFirst;
	unsigned int	uFirstTime;
	unsigned short	uLTapCount;
	POINT_FLOAT 	ptLast;
	unsigned int	uLastTime;
	unsigned char	bIsDTap;
} TOUCH_DATA, *PTOUCH_DATA;
typedef struct
{
	unsigned char	bButton;
	POINT_DELTA		cPt;
	char			cWheel;
} RELMOUSE_INPUT;
typedef struct
{
	unsigned char	bButton;
	POINT_WORD		wPt;
	char			cWheel;
} ABSMOUSE_INPUT;
typedef struct
{
	unsigned char	bButton;	// 7(RGui) 6(RAlt) 5(RSft) 4(RCtl) 3(LGui) 2(LAlt) 1(LSft) 0(LCtl)
	unsigned char	bKeys[5];	// 0(released)
} KEYBOARD_INPUT;
typedef struct
{
	struct
	{
		unsigned char	bStatus;	// b[7:2](None), b[1](InRange), b[0](TipSw)
		unsigned char	bId;
		POINT_WORD		wPt;
	} td[TOUCH_DATA_MAX_NUM];
	unsigned char	bCount;
} TOUCH_INPUT;
typedef struct
{
	unsigned char	bReportId;	// 0x11(m), 0x12(k), 0x13(t)
	union
	{
		RELMOUSE_INPUT	r;	// 4 = Button(1), rX(1), rY(1), Wheel(1)
		ABSMOUSE_INPUT	a;	// 6 = Button(1), aX(2), aY(2), Wheel(1)
		KEYBOARD_INPUT	k;	// 6 = Button(1), Key1(1), ... Key5(1)
		TOUCH_INPUT		t;	// 6*n + 1 = Contact(6), ..., Contact(6), ..., Count(1)
		unsigned char	bRawInput[6*TOUCH_DATA_MAX_NUM + 1];
	};
} INPUT_REPORT, *PINPUT_REPORT;
#pragma pack()


#define	CMD_INIT				0x01	// ostype(u8) / state_xxx(u8), board_addr(u8)
#define	CMD_RESET				0x02	// reset_xxx(u8) / reset_xxx(u8)
#define	CMD_GET_VERSION			0x03	// none / version_data(struct)
#define	CMD_UPGRADE_FWINFO		0x04	// fwinfo_data(struct) / fwinfo_data(struct)
#define	CMD_UPGRADE_FWDATA		0x05	// fwdata_data(struct) / fwdata_data(struct)
#define	CMD_GET_STATE			0x06	// none / state_xxx(u8)
#define	CMD_SET_STATE			0x07	// state_xxx(u8) / state_xxx(u8)
#define	CMD_SET_BUZZER			0x08	// 10msec(u8) / none
#define	CMD_FLASH_ERASE			0x09	// flashsector(u8) / flashsector(u8)
#define	CMD_EEPROM_READ			0x0A	// eeprom_data(struct) / eeprom_data(struct)
#define	CMD_EEPROM_WRITE		0x0B	// eeprom_data(struct) / eeprom_data(struct)
//...
#define	CMD_GET_TOUCH_CONFIG	0x31	// none / touchconfig_data(struct) - only touch
#define	CMD_SET_TOUCH_CONFIG	0x32	// touchconfig_data(struct) or 0(default) / touchconfig_data(struct) - only touch
#define	CMD_SET_TOUCH_FILTER	0x33	// filternum(u8) / filternum(u8) - only touch
#define	CMD_SET_INPUT_MODE		0x34	// inputmode(u8) / inputmode(u8) - only touch
#define	CMD_SET_PWMS			0x35	// pwms[4](u8) / pwms[4](u8) - only touch
#define	CMD_SET_TIME_TAP		0x36	// timetap(u8) / timetap(u8) - only touch
#define	CMD_SET_TIME_LTAP		0x37	// timeltap(u8) / timeltap(u8) - only touch
#define	CMD_SET_AREA_TAP		0x38	// areatap(u8) / areatap(u8) - only touch
#define	CMD_SET_AREA_DTAP		0x39	// areadtap(u8) / areadtap(u8) - only touch
#define	CMD_SET_AREA_PALM		0x3A	// areapalm(u8) / areapalm(u8) - only touch
#define	CMD_SET_BEEP_ALERT		0x3B	// beepalert(u8) / beepalert(u8) - only touch
#define	CMD_SET_BEEP_CLICK		0x3C	// beepclick(u8) / beepclick(u8) - only touch
#define	CMD_SET_NOSEND			0x3D	// nosend(u8) / nosend(u8) - only touch
#define	CMD_SET_ACCEL			0x3E	// accel(u16) / accel(u16) - only touch
//...
#define	CMD_GET_TOUCH_GESTURE	0x51	// none / gesture_data(struct) - only touch
#define	CMD_SET_TOUCH_GESTURE	0x52	// gesture_data(struct) or 0(default) / gesture_data(struct) - only touch
//...
#define	CMD_GET_CAMERA_CONFIG	0x91	// none / cameraconfig_data(struct) - only camera
#define	CMD_SET_CAMERA_CONFIG	0x92	// cameraconfig_data(struct) or 0(default) / cameraconfig_data(struct) - only camera
#define	CMD_SET_YCENTER			0x93	// ycenter(s16) / ycenter(s16) - only camera
#define	CMD_SET_XSTART			0x94	// xstart(u16) / xstart(u16) - only camera
#define	CMD_SET_XEND			0x95	// xend(u16) / xend(u16) - only camera
#define	CMD_SET_THRESHOLD		0x96	// threshold(u8) / threshold(u8) - only camera
#define	CMD_SET_MINWIDTH		0x97	// minwidth(u8) / minwidth(u8) - only camera
#define	CMD_SET_AVERAGELIGHT	0x98	// averagelight(u8) / averagelight(u8) - only camera
#define	CMD_SET_COEFFS			0x99	// coeffs(float[8]) / coeffs(float[8]) - only camera
//...
#define	CMD_SIDEVIEW_START		0xB1	// start(u8) / start(u8) - only camera
#define	CMD_DETECTION_START		0xB2	// start(u8) / start(u8) - only camera
#define	CMD_CALIBRATION_START	0xB3	// index(u8) / index(u8) - only touch
//...
#define	CMD_RESULT_SUCCESS		0xC1	// cmd_xxx(u8), ...
#define	CMD_RESULT_ERROR		0xC2	// cmd_xxx(u8), err_xxx(u8)
//...
#define	EVT_CAMERA_INIT			0xE1	// state_xxx(u8)
#define	EVT_IMAGE_SIDEVIEW		0xE2	// buf...
#define	EVT_IMAGE_DETECTION		0xE3	// buf...
#define	EVT_RADIAN_DATA			0xE4	// radian_data(struct)
#define	EVT_LINEEQ_DATA			0xE5	// lineeq_data(struct)
#define	EVT_CAMERA_PING			0xE6	// none
//...



typedef void (*STATE_PROC)(unsigned char state);
typedef struct
{
	unsigned char	state;
	STATE_PROC		pfx;
} DECODE_STATE, *PDECODE_STATE;

typedef void (*CMD_PROC)(void *ctx, unsigned char cmd, unsigned char dev,
	unsigned char dlen, unsigned char *data);
typedef struct
{
	unsigned char	cmd;
	CMD_PROC		pfx;
} DECODE_CMD, *PDECODE_CMD;


#endif	//__MT_CAMERA_H__

